package pl.edu.agh.neurony.gui;

import javax.swing.JOptionPane;

import pl.edu.agh.neurony.exceptions.BadNeuronInitiationException;
import pl.edu.agh.neurony.exceptions.LearningException;
import pl.edu.agh.neurony.exceptions.NeuronNetException;
import pl.edu.agh.neurony.logic.Net;

public class LearningComponent {

	private Net net = Net.getInstance();
	private NetCreationWindow parent;

	public static final Integer CP = 1;
	public static final Integer BP = 2;

	private int lastChoice = -1;
	private int learningSteps;
	private Double learningFactor;
	private Double momentum;

	public LearningComponent(NetCreationWindow parent) {
		this.parent = parent;
	}

	public void learn() {
		lastChoice = JOptionPane.showOptionDialog(parent, "Choose learning rule", "learning",
				JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, new Object[] { "Back propagation",
						"Counter propagation" }, 0);
		try {
			askForOverallParams();
			parent.layerStructurePanel.fileInputButton.doClick();
			parent.layerStructurePanel.readDataButton.doClick();
			switch (lastChoice) {
				case 0: {
					net.setLearningParams(0, learningFactor, 0, 0, momentum);
					net.learnBackProp(learningSteps);
					break;
				}
				case 1: {
					setLearningParamsForCP();
					net.learnCounterProp(CP, learningSteps);
					break;
				}
			}
			NeuralGraph.getInstance(false).repaint();
		} catch (BadNeuronInitiationException e) {
			e.printStackTrace();
		} catch (LearningException e) {
			e.printStackTrace();
		} catch (NeuronNetException e) {
			e.printStackTrace();
		}
	}
	
	void setLearningParamsForCP() {
		Double conscienceFactor = Double.parseDouble(JOptionPane.showInputDialog(parent, "Conscience:", "1"));
		int neighborhood = Integer.parseInt(JOptionPane.showInputDialog(parent, "Neighborhood:", 1));
		int neighborhoodSize = Integer.parseInt(JOptionPane.showInputDialog(parent, "NeighborhoodSize:", 1));
		net.setLearningParams(neighborhood, learningFactor, conscienceFactor, neighborhoodSize, momentum);
	}
	
	private void askForOverallParams() {
		learningFactor = Double.parseDouble(JOptionPane.showInputDialog(parent, "Learning factor:", "0.7"));
		learningSteps = Integer.parseInt(JOptionPane.showInputDialog(parent, "Steps:", "30000"));
		momentum = Double.parseDouble(JOptionPane.showInputDialog(parent, "Momentum:", "0.7"));
	}
	
	void setLearningParams() {
		askForOverallParams();
		setLearningParamsForCP();
	}
}
